home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / winlib.lzh / WINLIB / RESOURCE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-31  |  13.0 KB  |  635 lines

  1. /********************************************************************
  2.  *                                                                    *
  3.  *    Resource manipulation module                                    *
  4.  *                                                                    *
  5.  *    Copyright (c) Clever Bits and Bitgate Software 1993    - 1994        *
  6.  *    All Rights Reserved.                                            *
  7.  *                                                                    *
  8.  *    This modules deals with resources and objects, loading, and        *
  9.  *    object fixation during the loading process.                        *
  10.  *                                                                    *
  11.  ********************************************************************
  12.  *                                                                    *
  13.  *    Update log:                                                        *
  14.  *                                                                    *
  15.  *    [1.11.93] Karl A. 0ygard                                        *
  16.  *                            - changed some code layout                *
  17.  *    [2.11.93] Karl A. 0ygard                                        *
  18.  *        rsrc_search            - removed; it was no longer required    *
  19.  *    [14.12.93 - 23.2.94] Ken Hollis and Oliver Groeger                *
  20.  *                            - added xrsrc source from InterFace 2.00*
  21.  *        xrsrc_load            - added internal title loading stuff...    *
  22.  *                                                                    *
  23.  *    Note: Resource files can be as large as 4294967295 bytes in        *
  24.  *    """"" length if needed.  (4.294 GB)                                *
  25.  *                                                                    *
  26.  ********************************************************************/
  27.  
  28. #include <aes.h>
  29. #include <tos.h>
  30. #include <stdio.h>
  31.  
  32. #include "winlib.h"
  33.  
  34. #ifndef    __XRSRC__
  35. #define    __XRSRC__
  36. #endif
  37.  
  38. #ifdef __TURBOC__
  39. #pragma warn -pia
  40. #endif
  41.  
  42. static int        pglobal[15];
  43. static int        *rs_global;
  44. static RSXHDR     *rs_hdr;
  45. static RSXHDR    hdr_buf;
  46. int                rsrc_objects, rsrc_trees;
  47.  
  48. LOCAL void rs_obfix (OBJECT *rs_otree, int rs_oobject);
  49. LOCAL void rs_sglobal (int *base);
  50. LOCAL int rs_free (int *base);
  51. LOCAL int rs_gaddr (int *base, int re_gtype, int re_gindex, OBJECT **re_gaddr);
  52. LOCAL int rs_sadd (int *base, int rs_stype, int rs_sindex, OBJECT *re_saddr);
  53. LOCAL int rs_load (int *global, const signed char *fname);
  54. LOCAL void *get_address (int type, int index);
  55. LOCAL void *get_sub (int index, long offset, int size);
  56. LOCAL int rs_read (int *global, const signed char *fname);
  57. LOCAL void rs_fixindex (int *global);
  58. LOCAL void do_rsfix (RSXHDR *hdr, unsigned long size);
  59. LOCAL void fix_treeindex (void);
  60. LOCAL void fix_ob (void);
  61. LOCAL void fix_tedinfo();
  62. LOCAL void fix_nptr (long index, int ob_type);
  63. LOCAL int fix_ptr (int type, long index);
  64. LOCAL int fix_long (long *lptr);
  65. LOCAL void fix_chp (int *pcoord, int flag);
  66.  
  67. /*
  68.  *    Free resource (unfix objects and free resource)
  69.  *
  70.  *    Returns: 0 on failure
  71.  */
  72. GLOBAL int Rsrc_Free(void)
  73. {
  74.     int i;
  75.     OBJECT *tree;
  76.  
  77.     rsrc_gaddr(0, 0, &tree);
  78.  
  79.     for (i = 0; i < rsrc_objects; i++)
  80.         unfix_object(tree + i);
  81.  
  82.     return rsrc_free();
  83. }
  84.  
  85. GLOBAL int xrsrc_load(const char *re_lpfname)
  86. {
  87.     int ret = TRUE;
  88.     char *title;
  89.  
  90.     WGrafMouse(LOAD_MOUSE);
  91.  
  92.     sprintf(title, "Loading %s", re_lpfname);
  93.     TChangeTitleText(title);
  94.  
  95.     if (ret = rsrc_load(re_lpfname)) {
  96.         int rsrc_header[18], i = 0;
  97.         OBJECT *tree;
  98.         FILE *file;
  99.         RSHDR *rsc;
  100.  
  101.         TChangeTitleText("Fixing objects...");
  102.  
  103.         WGrafMouse(INIT_MOUSE);
  104.  
  105.         file = fopen(re_lpfname, "rb");
  106.         fread(&rsrc_header, sizeof(int), 18, file);
  107.         fclose(file);
  108.  
  109.         rsc = (RSHDR *) rsrc_header;
  110.         rsrc_objects = rsc->rsh_nobs;
  111.         rsrc_trees = rsc->rsh_ntree;
  112.  
  113.         for (; i < rsc->rsh_ntree; i++) {
  114.             rsrc_gaddr(R_TREE, i, &tree);
  115.             if (!fix_object(tree, TRUE)) {
  116.                 Rsrc_Free();
  117.                 WGrafMouse(ARROW);
  118.                 return 0;
  119.             }
  120.         }
  121.  
  122.         TEndTitle();
  123.     }
  124.  
  125.     WGrafMouse(ARROW);
  126.     return ret;
  127. }
  128.  
  129. /*
  130.  *    Load resource file
  131.  *
  132.  *    re_lpfname    = Name of file to load
  133.  */
  134. /*GLOBAL int xrsrc_load (const signed char *re_lpfname)
  135. {
  136.     return (rs_load (pglobal, re_lpfname));
  137. }
  138.  
  139. /*
  140.  *    Free resource memory
  141.  */
  142. GLOBAL int xrsrc_free (void)
  143. {
  144.     return (rs_free (pglobal));
  145. }
  146.  
  147. /*
  148.  *    Get resource address
  149.  *
  150.  *    re_gtype    = index to type of object to get
  151.  *    re_gindex    = index of object to get
  152.  *    re_gaddr    = address (returned) of requested object
  153.  */
  154. GLOBAL int xrsrc_gaddr (int re_gtype, int re_gindex, void *re_gaddr)
  155. {
  156.     return (rs_gaddr (pglobal, re_gtype, re_gindex, re_gaddr));
  157. }
  158.  
  159. /*
  160.  *    Save resource address
  161.  *
  162.  *    re_stype    = Type of object to add
  163.  *    re_sindex    = Number of object to add
  164.  *    re_saddr    = Address of the object to add
  165.  */
  166. GLOBAL int xrsrc_saddr (int re_stype, int re_sindex, void *re_saddr)
  167. {
  168.     return (rs_sadd (pglobal, re_stype, re_sindex, re_saddr));
  169. }
  170.  
  171. /*
  172.  *    Fix resource coordinates
  173.  *
  174.  *    re_otree    = Object tree to fix
  175.  *    re_oobject    = Object of unfixed coordinates
  176.  */
  177. GLOBAL int xrsrc_obfix (OBJECT *re_otree, int re_oobject)
  178. {
  179.     rs_obfix (re_otree, re_oobject);
  180.  
  181.     return (TRUE);
  182. }
  183.  
  184. /*
  185.  *    Fix object (actual routine)
  186.  *
  187.  *    rs_otree    = Object tree to fix
  188.  *    rs_oobject    = Actual object to fix
  189.  */
  190. LOCAL void rs_obfix (OBJECT *rs_otree, int rs_oobject)
  191. {
  192.     int *coord;
  193.     int tmp = FALSE;
  194.     int count = 0;
  195.  
  196.     coord = &rs_otree[rs_oobject].ob_x;
  197.  
  198.     while (count++ < 4)
  199.     {
  200.         fix_chp (coord++, tmp);
  201.         tmp = tmp ? FALSE : TRUE;
  202.     }
  203.  
  204.     return;
  205. }
  206.  
  207. /*
  208.  *    Save global information
  209.  *
  210.  *    base    = base address of resource file
  211.  */
  212. LOCAL void rs_sglobal (int *base)
  213. {
  214.     rs_global = base;
  215.     rs_hdr = (RSXHDR *)*(long *)&rs_global[7];
  216.  
  217.     return;
  218. }
  219.  
  220. /*
  221.  *    Free resource memory
  222.  *
  223.  *    base        = base address of resource file
  224.  */
  225. LOCAL int rs_free (int *base)
  226. {
  227.     rs_global = base;
  228.  
  229.     if (free ((RSXHDR *)*(long *)&rs_global[7]))
  230.         return (FALSE);
  231.  
  232.     return (TRUE);
  233. }
  234.  
  235. /*
  236.  *    Get resource information
  237.  *
  238.  *    base        = base address of resource file
  239.  *    re_gtype    = type of object to get info on
  240.  *    re_gindex    = number of object to get info on
  241.  *    re_gaddr    = actual address of object
  242.  */
  243. LOCAL int rs_gaddr (int *base, int re_gtype, int re_gindex, OBJECT **re_gaddr)
  244. {
  245.     rs_sglobal (base);
  246.  
  247.     *re_gaddr = get_address (re_gtype, re_gindex);
  248.  
  249.     if (*re_gaddr == (OBJECT *)NULL)
  250.         return (FALSE);
  251.  
  252.     return (TRUE);
  253. }
  254.  
  255. /*
  256.  *    Save resource information
  257.  *
  258.  *    base        = base of resource file
  259.  *    rs_stype    = type of object to save
  260.  *    rs_sindex    = number of object to save
  261.  *    re_saddr    = address of object to save
  262.  */
  263. LOCAL int rs_sadd (int *base, int rs_stype, int rs_sindex, OBJECT *re_saddr)
  264. {
  265.     OBJECT *old_addr;
  266.  
  267.     rs_sglobal (base);
  268.  
  269.     old_addr = get_address (rs_stype, rs_sindex);
  270.  
  271.     if (old_addr == (OBJECT *)NULL)
  272.         return (FALSE);
  273.  
  274.     *old_addr = *re_saddr;
  275.  
  276.     return (TRUE);
  277. }
  278.  
  279. /*
  280.  *    Load resource file and fix coordinates
  281.  *
  282.  *    global        = global resource information
  283.  *    fname        = name of resource to load
  284.  */
  285. LOCAL int rs_load (int *global, const signed char *fname)
  286. {
  287.     if (!rs_read (global, fname))
  288.         return (FALSE);
  289.  
  290.     rs_fixindex (global);
  291.  
  292.     return (TRUE);
  293. }
  294.  
  295. /*
  296.  *    Return address of an object
  297.  *
  298.  *    type    = object type
  299.  *    index    = object resource index
  300.  */
  301. LOCAL void *get_address (int type, int index)
  302. {
  303.     void *the_addr = (void *)NULL;
  304.     union
  305.     {
  306.         void    *dummy;
  307.         signed char    *string;
  308.         OBJECT    **dpobject;
  309.         OBJECT    *object;
  310.         TEDINFO    *tedinfo;
  311.         ICONBLK    *iconblk;
  312.         BITBLK    *bitblk;
  313.     } all_ptr;
  314.  
  315.     switch (type)
  316.     {
  317.         case R_TREE:
  318.             all_ptr.dpobject = (OBJECT **)(*(long **)&rs_global[5]);
  319.             the_addr = all_ptr.dpobject[index];
  320.             break;
  321.  
  322.         case R_OBJECT:
  323.             the_addr = get_sub (index, rs_hdr->rsh_object, sizeof(OBJECT));
  324.             break;
  325.  
  326.         case R_TEDINFO:
  327.         case R_TEPTEXT:
  328.             the_addr = get_sub (index, rs_hdr->rsh_tedinfo, sizeof(TEDINFO));
  329.             break;
  330.  
  331.         case R_ICONBLK:
  332.         case R_IBPMASK:
  333.             the_addr = get_sub (index, rs_hdr->rsh_iconblk, sizeof(ICONBLK));
  334.             break;
  335.  
  336.         case R_BITBLK:
  337.         case R_BIPDATA:
  338.             the_addr = get_sub (index, rs_hdr->rsh_bitblk, sizeof(BITBLK));
  339.             break;
  340.  
  341.         case R_OBSPEC:
  342.             all_ptr.object = get_address(R_OBJECT, index);
  343.             the_addr = &all_ptr.object->ob_spec;
  344.             break;
  345.  
  346.         case R_TEPVALID:
  347.         case R_TEPTMPLT:
  348.             all_ptr.tedinfo = get_address(R_TEDINFO, index);
  349.             if (type == R_TEPVALID)
  350.                 the_addr = &all_ptr.tedinfo->te_pvalid;
  351.             else
  352.                 the_addr = &all_ptr.tedinfo->te_ptmplt;
  353.             break;
  354.  
  355.         case R_IBPDATA:
  356.         case R_IBPTEXT:
  357.             all_ptr.iconblk = get_address(R_ICONBLK, index);
  358.             if (type == R_IBPDATA)
  359.                 the_addr = &all_ptr.iconblk->ib_pdata;
  360.             else
  361.                 the_addr = &all_ptr.iconblk->ib_ptext;
  362.             break;
  363.  
  364.         case R_STRING:
  365.             the_addr = get_sub (index, rs_hdr->rsh_frstr, sizeof (signed char *));
  366.             the_addr = (void *)*(signed char *)the_addr;
  367.             break;
  368.  
  369.         case R_IMAGEDATA:
  370.             the_addr = get_sub (index, rs_hdr->rsh_imdata, sizeof (signed char *));
  371.             the_addr = (void *)*(signed char *)the_addr;
  372.             break;
  373.  
  374.         case R_FRIMG:
  375.             the_addr = get_sub (index, rs_hdr->rsh_frimg, sizeof (signed char *));
  376.             the_addr = (void *)*(signed char *)the_addr;
  377.             break;
  378.  
  379.         case R_FRSTR:
  380.             the_addr = get_sub (index, rs_hdr->rsh_frstr, sizeof (signed char *));
  381.             break;
  382.     }
  383.  
  384.     return (the_addr);
  385. }
  386.  
  387. /*
  388.  *    Get object address chunk
  389.  *
  390.  *    index    = index of the object to get
  391.  *    offset    = size of move
  392.  *    size    = size of chunk to return
  393.  */
  394. LOCAL void *get_sub (int index, long offset, int size)
  395. {
  396.     unsigned char *ptr = (unsigned char *)rs_hdr;
  397.  
  398.     ptr += offset;
  399.     ptr += (index * size);
  400.  
  401.     return ((void *)ptr);
  402. }
  403.  
  404. /*
  405.  *    Actual routine to read resource file
  406.  *
  407.  *    global    = global resource file index
  408.  *    fname    = name of file to load
  409.  */
  410. LOCAL int rs_read (int *global, const signed char *fname)
  411. {
  412.     int fh;
  413.     signed char tmpnam[128];
  414.  
  415.     strcpy (tmpnam, fname);
  416.  
  417.     if (!shel_find (tmpnam))
  418.         return (FALSE);
  419.  
  420.     rs_global = global;
  421.  
  422.     if ((fh = Fopen (tmpnam, 0)) < 0)
  423.         return (FALSE);
  424.  
  425.     if (Fread (fh, sizeof(RSXHDR), &hdr_buf) != sizeof (RSXHDR))
  426.     {
  427.         Fclose (fh);
  428.         return (FALSE);
  429.     }
  430.  
  431.     if ((rs_hdr = (RSXHDR *)malloc (hdr_buf.rsh_rssize)) == NULL)
  432.     {
  433.         Fclose (fh);
  434.         return (FALSE);
  435.     }
  436.  
  437.     Fseek (0L, fh, 0);
  438.  
  439.     if (Fread (fh, hdr_buf.rsh_rssize, &rs_hdr) != hdr_buf.rsh_rssize)
  440.     {
  441.         Fclose (fh);
  442.         return (FALSE);
  443.     }
  444.  
  445.     do_rsfix (rs_hdr, hdr_buf.rsh_rssize);
  446.  
  447.     Fclose (fh);
  448.  
  449.     return (TRUE);
  450. }
  451.  
  452. /*
  453.  *    Fix object positions
  454.  *
  455.  *    global    = pointer to resource information
  456.  */
  457. LOCAL void rs_fixindex (int *global)
  458. {
  459.     rs_sglobal (global);
  460.  
  461.     fix_ob ();
  462. }
  463.  
  464. /*
  465.  *    Locate and fix objects
  466.  *
  467.  *    hdr        = header information of resource
  468.  *    size    = size of resource file
  469.  */
  470. LOCAL void do_rsfix (RSXHDR *hdr, unsigned long size)
  471. {
  472.     rs_global[7] = ((long)hdr >> 16) & 0xFFFF;
  473.     rs_global[8] = (long)hdr & 0xFFFF;
  474.     rs_global[9] = size;
  475.  
  476.     fix_treeindex ();
  477.     fix_tedinfo ();
  478.  
  479.     fix_nptr (hdr->rsh_nib - 1, R_IBPMASK);
  480.     fix_nptr (hdr->rsh_nib - 1, R_IBPDATA);
  481.     fix_nptr (hdr->rsh_nib - 1, R_IBPTEXT);
  482.  
  483.     fix_nptr (rs_hdr->rsh_nbb - 1, R_BIPDATA);
  484.     fix_nptr (rs_hdr->rsh_nstring - 1, R_FRSTR);
  485.     fix_nptr (rs_hdr->rsh_nimages - 1, R_FRIMG);
  486. }
  487.  
  488. /*
  489.  *    Fix indices of all trees
  490.  */
  491. LOCAL void fix_treeindex (void)
  492. {
  493.     OBJECT **adr;
  494.     long   count;
  495.  
  496.     count = rs_hdr->rsh_ntree - 1L;
  497.  
  498.     adr = get_sub (0, rs_hdr->rsh_trindex, sizeof (OBJECT *));
  499.  
  500.     rs_global[5] = ((long)adr >> 16) & 0xFFFF;
  501.     rs_global[6] = (long)adr & 0xFFFF;
  502.  
  503.     while (count >= 0)
  504.     {
  505.         fix_long ((long *)(count * sizeof (OBJECT *) + (long)adr));
  506.         count--;
  507.     }
  508. }
  509.  
  510. /*
  511.  *    Fix objects
  512.  */
  513. LOCAL void fix_ob (void)
  514. {
  515.     int      count;
  516.     OBJECT *obj;
  517.  
  518.     count = rs_hdr->rsh_nobs - 1;
  519.  
  520.     while (count >= 0)
  521.     {
  522.         obj = get_address (R_OBJECT, count);
  523.         rs_obfix (obj, 0);
  524.         if ((obj->ob_type & 0xff) != G_BOX && (obj->ob_type & 0xff) != G_IBOX && (obj->ob_type & 0xff) != G_BOXCHAR)
  525.             fix_long ((long *)&obj->ob_spec);
  526.  
  527.         count--;
  528.     }
  529. }
  530.  
  531. /*
  532.  *    Fix Text Editing Dialog info
  533.  */
  534. LOCAL void fix_tedinfo()
  535. {
  536.     long        count;
  537.     TEDINFO *tedinfo;
  538.  
  539.     count = rs_hdr->rsh_nted - 1;
  540.  
  541.     while (count >= 0)
  542.     {
  543.         tedinfo = get_address (R_TEDINFO, count);
  544.  
  545.         if (fix_ptr (R_TEPTEXT, count))
  546.             tedinfo->te_txtlen = strlen (tedinfo->te_ptext) + 1;
  547.  
  548.         if (fix_ptr (R_TEPTMPLT, count))
  549.             tedinfo->te_tmplen = strlen (tedinfo->te_ptmplt) + 1;
  550.  
  551.         fix_ptr (R_TEPVALID, count);
  552.  
  553.         count--;
  554.     }
  555.  
  556.     return;
  557. }
  558.  
  559. /*
  560.  *    Fix pointer information
  561.  *
  562.  *    index    = index of object
  563.  *    ob_type    = new object type
  564.  */
  565. LOCAL void fix_nptr (long index, int ob_type)
  566. {
  567.     while (index >= 0)
  568.         fix_long (get_address(ob_type, index--));
  569. }
  570.  
  571. /*
  572.  *    Fix memory pointer
  573.  *
  574.  *    type    = type of object to fix
  575.  *    index    = its index
  576.  */
  577. LOCAL int fix_ptr (int type, long index)
  578. {
  579.     return (fix_long (get_address (type, index)));
  580. }
  581.  
  582. /*
  583.  *    Fix pointer information
  584.  *
  585.  *    lptr    = pointer to information
  586.  */
  587. LOCAL int fix_long (long *lptr)
  588. {
  589.     long base;
  590.  
  591.     base = *lptr;
  592.     if (base == 0L)
  593.         return (FALSE);
  594.  
  595.     base += (long)rs_hdr;
  596.  
  597.     *lptr = base;
  598.  
  599.     return (TRUE);
  600. }
  601.  
  602. /*
  603.  *    Fix character position
  604.  *
  605.  *    pcoord    = coordinates of object
  606.  *    flag    = flag of whether to fix or not
  607.  */
  608. LOCAL void fix_chp (int *pcoord, int flag)
  609. {
  610.     int ncoord;
  611.  
  612.     ncoord = *pcoord & 0xff;
  613.  
  614.     if (!flag && ncoord == 0x50)
  615.         ncoord = desk.g_w;                                        /* desk.g_w = Breite des Bildschirms in Pixel */
  616.     else
  617.         ncoord *= (flag ? gr_bh : gr_bw);    /* gr_bw, gr_bh = Zeichenbreite, Zeichenhöhe in Pixel */
  618.  
  619.     if (((*pcoord >> 8) & 0xff) > 0x80)
  620.         ncoord += (((*pcoord >> 8) & 0xff) | 0xff00);
  621.     else
  622.         ncoord += ((*pcoord >> 8) & 0xff);
  623.  
  624.     *pcoord = ncoord;
  625. } */
  626.  
  627. GLOBAL void RFix_ObjectPos(OBJECT *obj)
  628. {
  629.     int i;
  630.  
  631.     i = -1;
  632.     do {
  633.         i++;
  634.         rsrc_obfix(obj, i);
  635.     } while(!(obj[i].ob_flags & LASTOB));
  636. }